home *** CD-ROM | disk | FTP | other *** search
- //• ------------------------------------------------------------------------------------------ •
- //•
- //• Copyright © 1996-1999 Apple Computer, Inc., All Rights Reserved
- //•
- //•
- //• You may incorporate this sample code into your applications without
- //• restriction, though the sample code has been provided "AS IS" and the
- //• responsibility for its operation is 100% yours. However, what you are
- //• not permitted to do is to redistribute the source as "DSC Sample Code"
- //• after having made changes. If you're going to re-distribute the source,
- //• we require that you make it clear in the source that the code was
- //• descended from Apple Sample Code, but that you've made changes.
- //•
- //• Authors:
- //• Chris De Salvo
- //•
- //• ------------------------------------------------------------------------------------------ •
-
- //• ------------------------------ Includes
-
- #include <Types.h>
- #include <Resources.h>
-
- #include <string.h>
-
- #include "DrawSprocket.h"
- #include "ErrorHandler.h"
- #include "Graphics.h"
- #include "MemoryHandler.h"
- #include "SIResources.h"
- #include "Sprite.h"
-
- //• ------------------------------ Private Definitions
-
- #define kFirstIconColor 1
- #define kLastIconColor 33
-
- #define kFirstBGColor 34
- #define kLastBGColor 183
-
- #define kFirstSpriteColor 184
- #define kLastSpriteColor 254
-
- //• ------------------------------ Private Types
- //• ------------------------------ Private Variables
-
- static DSpAltBufferReference gUnderlay;
- static CTabHandle gGameCLUT;
-
- //• ------------------------------ Private Functions
-
- static void GraphicsUpdateScreenPalette(UInt16 inFirstColor, UInt16 inLastColor);
- static void GraphicsCreateUnderlay(void);
- static void GraphicsSelectContext(SInt16 modifiers);
- static void GraphicsInitAttributes(DSpContextAttributes *inAttributes);
-
- //• ------------------------------ Public Variables
-
- DSpContextReference gDisplayContext;
- DSpContextAttributes gDisplayAttributes;
- GDHandle gGameGDH;
-
- const RGBColor rgbBlack = { 0x0000, 0x0000, 0x0000 };
- const RGBColor rgbWhite = { 0xFFFF, 0xFFFF, 0xFFFF };
- const RGBColor rgbRed = { 0xFFFF, 0x0000, 0x0000 };
- const RGBColor rgbBlue = { 0x0000, 0x0000, 0xFFFF };
- const RGBColor rgbYellow = { 0xFFFF, 0xFFFF, 0x0000 };
- const RGBColor rgbGreen = { 0x0000, 0xFFFF, 0x0000 };
-
- #pragma mark ————— Startup/Shutdown —————
-
- //• -------------------- GraphicsInit
-
- void
- GraphicsInit(SInt16 modifiers)
- {
- CGrafPtr backBuffer;
- OSErr theErr;
- Rect r = { 40, 40, 100, 100 };
-
- theErr = DSpStartup();
- if (theErr)
- FatalError("GraphicsInit: DSpStartup() failed!!!!");
-
- //• CLUT 8 is the standard 8-bit color system color table and is
- //• always present
- gGameCLUT = GetCTable(8);
- DetachResource((Handle) gGameCLUT);
-
- //• Define and create our drawing context
- GraphicsSelectContext(modifiers);
-
- //• Add our various colors to the color table
- GraphicsMergeCLUT(128, kFirstIconColor, kLastIconColor);
- GraphicsMergeCLUT(kPICTGasCloud, kFirstBGColor, kLastBGColor);
- GraphicsMergeCLUT(kCLUTSprites, kFirstSpriteColor, kLastSpriteColor);
-
- //• Create our underlay and load a picture into it
- GraphicsCreateUnderlay();
- GraphicsLoadBackground(kPICTGasCloud);
-
- //• Swap the buffers once to get the underlay image on the screen
- DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &backBuffer);
- DSpContext_InvalBackBufferRect(gDisplayContext, &backBuffer->portRect);
- GraphicsUpdateScreen();
-
- //• Fade up from black and then put the context in the paused state
- //• so that the user has access to the menu bar.
- DSpContext_FadeGammaIn(nil, nil);
- GraphicsPaused();
- }
-
- //• -------------------- GraphicsReset
-
- void
- GraphicsReset(void)
- {
- DSpContext_FadeGammaOut(nil, nil);
- GraphicsInactive();
- DSpContext_FadeGammaIn(nil, nil);
-
- DSpContext_Release(gDisplayContext);
- DSpShutdown();
- }
-
- #pragma mark ————— Context Management —————
-
- //• -------------------- GraphicsSelectContext
-
- static void
- GraphicsSelectContext(SInt16 modifiers)
- {
- OSStatus theError;
- DisplayIDType displayID;
-
- //• Initialize our context description
- GraphicsInitAttributes(&gDisplayAttributes);
-
- //• Tell DrawSprocket the exact needs we have for our game
- gDisplayAttributes.displayWidth = 640;
- gDisplayAttributes.displayHeight = 480;
- gDisplayAttributes.colorNeeds = kDSpColorNeeds_Require;
- gDisplayAttributes.backBufferDepthMask = kDSpDepthMask_8;
- gDisplayAttributes.displayDepthMask = kDSpDepthMask_8;
- gDisplayAttributes.backBufferBestDepth = 8;
- gDisplayAttributes.displayBestDepth = 8;
- gDisplayAttributes.pageCount = 2;
- gDisplayAttributes.colorTable = gGameCLUT;
-
- //• Find the best context for these attributes
- //• This call will check to see if multiple monitors can handle the request
- //• If there is more than one valid device it will put up the selection interface
- theError = DSpUserSelectContext(&gDisplayAttributes, 0L, nil, &gDisplayContext);
-
- if (theError)
- FatalError("A suitable display context could not be found.");
-
- if (modifiers & optionKey)
- gDisplayAttributes.contextOptions |= kDSpContextOption_DontSyncVBL;
-
- //• Page flipping only works on 7500/7600/8500/8600 machines and only when
- //• there is >= 4 MB of VRAM. There are very few of these machines in
- //• existance so turning on this option is not recommended.
- //• gDisplayAttributes.contextOptions |= kDSpContextOption_PageFlip;
-
- //• Set the blanking color to black
- DSpSetBlankingColor(&rgbBlack);
-
- //• Find the DisplayID for this draw context and then find the GDevice
- //• that goes along with it. We need this because if we need to perform
- //• QuickDraw operations in a context that isn't on the main monitor then
- //• we need to have the proper GDevice set or QuickDraw loses its mind.
- theError = DSpContext_GetDisplayID(gDisplayContext, &displayID);
- if (theError)
- FatalError("DSpContext_GetDisplayID() had an error.");
-
- theError = DMGetGDeviceByDisplayID(displayID, &gGameGDH, false);
- if (theError)
- FatalError("DMGetGDeviceByDisplayID() had an error.");
-
- //• Reserve the draw context so that we get the attributes we want
- theError = DSpContext_Reserve(gDisplayContext, &gDisplayAttributes);
- if (theError)
- FatalError("Could not reserve display context.");
-
- //• Fade the screen to black and make our context active
- DSpContext_FadeGammaOut(nil, nil);
- GraphicsActive();
- }
-
- //• -------------------- GraphicsInitAttributes
-
- static void
- GraphicsInitAttributes(DSpContextAttributes *inAttributes)
- {
- if (! inAttributes)
- FatalError("Nil context passed to MyInitAttributes().");
-
- memset(inAttributes, 0, sizeof (DSpContextAttributes));
- }
-
- //• -------------------- GraphicaCreateUnderlay
-
- static void
- GraphicsCreateUnderlay(void)
- {
- OSStatus theError;
-
- //• Create a new alt buffer which mimics the onscreen display
- theError = DSpAltBuffer_New(gDisplayContext, true, 0L, &gUnderlay);
- if (theError)
- FatalError("Could not create underlay buffer.");
-
- //• Make it the active underlay
- theError = DSpContext_SetUnderlayAltBuffer(gDisplayContext, gUnderlay);
- if (theError)
- FatalError("Could not set underlay buffer.");
- }
-
- //• -------------------- GraphicsGetUnderlayGrafPort
-
- void
- GraphicsGetUnderlayGrafPort(CGrafPtr *underlay, GDHandle *device)
- {
- DSpAltBuffer_GetCGrafPtr(gUnderlay, kDSpBufferKind_Normal, underlay, device);
- }
-
- #pragma mark ————— Image Management —————
-
- //• -------------------- GraphicsLoadBackground
-
- void
- GraphicsLoadBackground(SInt16 whichBG)
- {
- GrafPtr oldPort;
- GDHandle oldDevice;
- GDHandle underlayDevice;
- PicHandle thePict;
- CGrafPtr backBuff;
- Rect r;
-
- thePict = GetPicture(whichBG);
- if (! thePict)
- FatalError("Could not load background.");
-
- //• Get a CGrafPtr reference to the underlay graphics buffer
- DSpAltBuffer_GetCGrafPtr(gUnderlay, kDSpBufferKind_Normal, &backBuff, &underlayDevice);
-
- GetPort(&oldPort);
- oldDevice = GetGDevice();
-
- SetPort((GrafPtr) backBuff);
- SetGDevice(underlayDevice);
-
- RGBForeColor(&rgbBlack);
- RGBBackColor(&rgbWhite);
-
- //• Fill the background with black
- PaintRect(&backBuff->portRect);
-
- HLock((Handle) thePict);
-
- SetRect(&r, 0, 0, 640, 440);
- DrawPicture(thePict, &r);
- KillPictureZ(&thePict);
-
- //• Invalidate the entire underlay so that all other back buffers
- //• get the new image copied up to them.
- DSpAltBuffer_InvalRect(gUnderlay, &backBuff->portRect);
-
- SetPort(oldPort);
- SetGDevice(oldDevice);
- }
-
- //• -------------------- GraphicsMergeCLUT
-
- void
- GraphicsMergeCLUT(SInt16 clutID, UInt16 firstColor, UInt16 lastColor)
- {
- CTabHandle ct;
- UInt32 i;
-
- //• Load the appropritate 'CLUT' resource
- ct = GetCTable(clutID);
- if (! ct)
- FatalError("Could not load color table for merge.");
-
- HLock((Handle) ct);
-
- //• Copy colors from it to our game color table
- for (i = firstColor; i <= lastColor; i++)
- {
- (**gGameCLUT).ctTable[i].rgb.red = (**ct).ctTable[i].rgb.red;
- (**gGameCLUT).ctTable[i].rgb.green = (**ct).ctTable[i].rgb.green;
- (**gGameCLUT).ctTable[i].rgb.blue = (**ct).ctTable[i].rgb.blue;
- }
-
- HUnlock((Handle) ct);
- ReleaseResource((Handle) ct);
-
- //• Make the new game color table the active color environment
- GraphicsUpdateScreenPalette(firstColor, lastColor);
- }
-
- //• -------------------- GraphicsUpdateScreenPalette
-
- static void
- GraphicsUpdateScreenPalette(UInt16 inFirstColor, UInt16 inLastColor)
- {
- OSStatus theError;
-
- //• Copy our game color table to our DrawSprocket context. This also
- //• updates the color environment of any buffers that we've allocated with
- //• DrawSprocket.
- theError = DSpContext_SetCLUTEntries(gDisplayContext, (**gGameCLUT).ctTable, inFirstColor, inLastColor - inFirstColor);
- if( theError )
- DebugStr("\p error from CLUT ");
- }
-
- //• -------------------- GraphicsSetRectDirty
-
- void
- GraphicsSetRectDirty(RectPtr r)
- {
- DSpContext_InvalBackBufferRect(gDisplayContext, r);
- }
-
- //• -------------------- GraphicsSetUnderlayRectDirty
-
- void
- GraphicsSetUnderlayRectDirty(RectPtr r)
- {
- DSpAltBuffer_InvalRect(gUnderlay, r);
- }
-
- //• -------------------- GraphicsUpdateScreen
-
- void
- GraphicsUpdateScreen(void)
- {
- DSpContext_SwapBuffers(gDisplayContext, nil, nil);
- }
-
- #pragma mark ————— Context State —————
-
- //• -------------------- GraphicsActive
-
- void
- GraphicsActive(void)
- {
- OSStatus theErr;
-
- HideCursor();
-
- theErr = DSpContext_SetState(gDisplayContext, kDSpContextState_Active);
- if (theErr)
- DebugStr("\pSetState active failed in GraphicsActive().");
- }
-
- //• -------------------- GraphicsPaused
-
- void
- GraphicsPaused(void)
- {
- DSpContext_SetState(gDisplayContext, kDSpContextState_Paused);
- ShowCursor();
- DrawMenuBar();
- }
-
- //• -------------------- GraphicsInactive
-
- void
- GraphicsInactive(void)
- {
- DSpContext_SetState(gDisplayContext, kDSpContextState_Inactive);
- ShowCursor();
- }
-
- //• -------------------- GraphicsDoUpdateEvent
-
- void
- GraphicsDoUpdateEvent(void)
- {
- GrafPtr savePort;
- GDHandle saveGDH;
-
- CGrafPtr backBuffer;
- CGrafPtr frontBuffer;
-
- DSpContext_GetFrontBuffer(gDisplayContext, &frontBuffer);
- DSpContext_GetBackBuffer(gDisplayContext, kDSpBufferKind_Normal, &backBuffer);
-
- GetPort(&savePort);
- saveGDH = GetGDevice();
-
- SetPort((GrafPtr) frontBuffer);
- SetGDevice(gGameGDH);
-
- ForeColor(blackColor);
- BackColor(whiteColor);
-
- CopyBits((BitMapPtr) *backBuffer->portPixMap, (BitMapPtr) *frontBuffer->portPixMap,
- &backBuffer->portRect, &frontBuffer->portRect, srcCopy, nil);
-
- SetPort(savePort);
- SetGDevice(saveGDH);
- }
-